package com.gt.quality.config;

import com.gt.quality.config.properties.ThreadPoolProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.VirtualThreadTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;


/**
 * 线程池配置
 *
 * @author: makeJava
 * @createTime: 2026-02-26 21:50
 * @since JDK 21 And SpringBoot 3.X
 */
@Configuration
@EnableAsync
@Slf4j
public class ExecutorPoolConfig {

    /**
     * 核心线程数 = cpu 核心数 + 1
     */
    private final int core = Runtime.getRuntime().availableProcessors() + 1;


    /**
     * Description: 线程池--原生线程池
     *
     * @author: makeJava
     */
    @Bean(name = "threadPoolTaskExecutor")
    @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
    public TaskExecutor threadPoolTaskExecutor(ThreadPoolProperties threadPoolProperties) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(core);
        executor.setMaxPoolSize(core * 2);
        executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
        executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
        // CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setThreadNamePrefix("async-task-");
        return executor;
    }

    /**
     * Description: 线程池--JDK21虚拟线程池
     *
     * @author: makeJava
     */
    @Bean(name = "threadPoolTaskExecutor")
    @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "false")
    public TaskExecutor virtualThreadTaskExecutor() {
        // JDK21--使用虚拟线程
        Runtime.Version version = Runtime.version();
        if (version.toString().contains("21.")) {
            return new VirtualThreadTaskExecutor("virtual-async-task-");
        }
        ThreadPoolProperties threadPoolProperties = new ThreadPoolProperties();
        threadPoolProperties.setQueueCapacity(100);
        threadPoolProperties.setKeepAliveSeconds(60);
        return threadPoolTaskExecutor(threadPoolProperties);
    }


}
